package api

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

// APIServer 表示REST API服务器
type APIServer struct {
	address     string
	handler     *APIHandler
	server      *http.Server
	userService UserService
}

// NewAPIServer 创建一个新的API服务器
func NewAPIServer(address string, mongoDBURI string) (*APIServer, error) {
	// 连接MongoDB
	clientOptions := options.Client().ApplyURI(mongoDBURI)
	client, err := mongo.Connect(context.Background(), clientOptions)
	if err != nil {
		return nil, fmt.Errorf("failed to connect to MongoDB: %w", err)
	}

	// 测试连接
	if err := client.Ping(context.Background(), nil); err != nil {
		return nil, fmt.Errorf("failed to ping MongoDB: %w", err)
	}

	// 初始化用户服务
	userService, err := NewMongoUserService(client, "aa", "aaa")
	if err != nil {
		return nil, fmt.Errorf("failed to create user service: %w", err)
	}

	// 初始化API处理器
	handler := NewAPIHandler(userService)

	// 创建服务器
	server := &APIServer{
		address:     address,
		handler:     handler,
		userService: userService,
	}

	return server, nil
}

// Start 启动API服务器
func (s *APIServer) Start() error {
	// 创建路由器
	router := s.handler.CreateRouter()

	// 设置HTTP服务器
	s.server = &http.Server{
		Addr:    s.address,
		Handler: router,
	}

	// 创建一个协程来启动服务器
	errChan := make(chan error, 1)
	go func() {
		log.Printf("Starting Northbound API server on %s", s.address)
		if err := s.server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			errChan <- fmt.Errorf("server error: %w", err)
		}
	}()

	// 等待中断信号
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)

	select {
	case <-quit:
		// 接收到中断信号，优雅关闭服务器
		log.Println("Shutting down Northbound API server...")
		ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
		defer cancel()
		if err := s.server.Shutdown(ctx); err != nil {
			return fmt.Errorf("server shutdown failed: %w", err)
		}
		log.Println("Northbound API server gracefully stopped")
	case err := <-errChan:
		// 服务器出错
		return err
	}

	return nil
}

// InitializeAdminUser 初始化管理员用户
func (s *APIServer) InitializeAdminUser() error {
	// 检查是否已存在管理员用户
	adminUser, err := s.userService.GetUserByUsername("admin")
	if err != nil && err.Error() != "user not found" {
		return fmt.Errorf("failed to check admin user: %w", err)
	}

	// 如果管理员用户已存在，跳过初始化
	if adminUser != nil {
		log.Println("Admin user already exists, skipping initialization")
		return nil
	}

	// 创建管理员用户
	admin := &User{
		Username:  "admin",
		Password:  "admin123", // 默认密码，应该在首次登录后更改
		Email:     "admin@iotcloud.com",
		Role:      "admin",
		Status:    "active",
		CreatedAt: time.Now(),
		UpdatedAt: time.Now(),
	}

	if err := s.userService.CreateUser(admin); err != nil {
		return fmt.Errorf("failed to create admin user: %w", err)
	}

	log.Println("Admin user created successfully")

	// 初始化角色权限
	adminPermissions := &RolePermission{
		Role: "admin",
		Permissions: []string{
			"read_user",
			"write_user",
			"delete_user",
			"manage_roles",
			"read_device",
			"write_device",
			"delete_device",
			"read_data",
			"write_data",
		},
	}

	operatorPermissions := &RolePermission{
		Role: "operator",
		Permissions: []string{
			"read_user",
			"read_device",
			"write_device",
			"read_data",
			"write_data",
		},
	}

	viewerPermissions := &RolePermission{
		Role: "viewer",
		Permissions: []string{
			"read_user",
			"read_device",
			"read_data",
		},
	}

	// 保存角色权限
	for _, rolePerm := range []*RolePermission{adminPermissions, operatorPermissions, viewerPermissions} {
		if err := s.userService.UpdateRolePermission(rolePerm); err != nil {
			return fmt.Errorf("failed to update role permissions for %s: %w", rolePerm.Role, err)
		}
	}

	log.Println("Role permissions initialized successfully")

	return nil
}
